package com.zlict.admin.controller;

import java.io.IOException;
import java.util.*;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import com.zlict.admin.domain.RdWorkhours;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zlict.common.annotation.Log;
import com.zlict.common.core.controller.BaseController;
import com.zlict.common.core.domain.AjaxResult;
import com.zlict.common.enums.BusinessType;
import com.zlict.admin.domain.RdPworkhours;
import com.zlict.admin.service.IRdPworkhoursService;
import com.zlict.common.utils.poi.ExcelUtil;
import com.zlict.common.core.page.TableDataInfo;
import com.zlict.system.mapper.SysUserMapper;
import com.zlict.common.core.domain.entity.SysUser;

/**
 * 研发人员工时Controller
 * 
 * @author ruoyi
 * @date 2025-06-12
 */
@RestController
@RequestMapping("/system/pworkhours")
public class RdPworkhoursController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(RdPworkhoursController.class);

    @Autowired
    private IRdPworkhoursService rdPworkhoursService;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询研发人员工时列表
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:list')")
    @GetMapping("/list")
    public TableDataInfo list(RdPworkhours rdPworkhours)
    {
        startPage();
        List<RdPworkhours> list = rdPworkhoursService.selectRdPworkhoursList(rdPworkhours);
        return getDataTable(list);
    }

    @GetMapping("/wklist")
    public TableDataInfo wklist(RdPworkhours rdPworkhours)
    {
        startPage();
        List<RdPworkhours> list = rdPworkhoursService.selectRdWorkhoursByUserList(rdPworkhours);
        return getDataTable(list);
    }

    /**
     * 导出研发人员工时列表
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:export')")
    @Log(title = "研发人员工时", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, RdPworkhours rdPworkhours)
    {
        List<RdPworkhours> list = rdPworkhoursService.selectRdPworkhoursList(rdPworkhours);
        ExcelUtil<RdPworkhours> util = new ExcelUtil<RdPworkhours>(RdPworkhours.class);
        util.exportExcel(response, list, "研发人员工时数据");
    }

    /**
     * 获取研发人员工时详细信息
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(rdPworkhoursService.selectRdPworkhoursById(id));
    }

    /**
     * 新增研发人员工时
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:add')")
    @Log(title = "研发人员工时", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody RdPworkhours rdPworkhours)
    {
        return toAjax(rdPworkhoursService.insertRdPworkhours(rdPworkhours));
    }

    /**
     * 修改研发人员工时
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:edit')")
    @Log(title = "研发人员工时", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody RdPworkhours rdPworkhours)
    {
        return toAjax(rdPworkhoursService.updateRdPworkhours(rdPworkhours));
    }

    /**
     * 删除研发人员工时
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:remove')")
    @Log(title = "研发人员工时", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(rdPworkhoursService.deleteRdPworkhoursByIds(ids));
    }

    /**
     * 导出研发人员工时导入模板
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:export')")
    @Log(title = "研发人员工时", businessType = BusinessType.EXPORT)
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(@RequestParam(required = true) String month, HttpServletResponse response) throws IOException {
        try {
            // 验证月份格式
            if (!month.matches("\\d{4}-\\d{2}")) {
                throw new RuntimeException("月份格式不正确，请使用yyyy-MM格式");
            }
            
            // 解析年月
            String[] yearMonth = month.split("-");
            int year = Integer.parseInt(yearMonth[0]);
            int monthNum = Integer.parseInt(yearMonth[1]);
            
            // 验证月份范围
            if (monthNum < 1 || monthNum > 12) {
                throw new RuntimeException("月份必须在1-12之间");
            }

            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("研发人员工时导入模板");

            // 设置列宽
            sheet.setColumnWidth(0, 15 * 256); // 工号
            sheet.setColumnWidth(1, 15 * 256); // 姓名
            sheet.setColumnWidth(2, 15 * 256); // 项目编号

            // 创建样式
            CellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);

            // 创建周末样式
            CellStyle weekendStyle = workbook.createCellStyle();
            weekendStyle.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());
            weekendStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            weekendStyle.setAlignment(HorizontalAlignment.CENTER);
            weekendStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            weekendStyle.setBorderTop(BorderStyle.THIN);
            weekendStyle.setBorderBottom(BorderStyle.THIN);
            weekendStyle.setBorderLeft(BorderStyle.THIN);
            weekendStyle.setBorderRight(BorderStyle.THIN);
            Font weekendFont = workbook.createFont();
            weekendFont.setColor(IndexedColors.RED.getIndex());
            weekendStyle.setFont(weekendFont);

            // 创建表头行
            Row headerRow = sheet.createRow(0);
            headerRow.setHeight((short) (20 * 20));
            
            // 添加工号、姓名和项目编号列
            String[] headers = {"工号", "姓名", "项目编号"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }

            // 获取当月天数
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, monthNum - 1, 1);
            int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

            // 添加日期列
            for (int day = 1; day <= daysInMonth; day++) {
                calendar.set(year, monthNum - 1, day);
                int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
                boolean isWeekend = (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY);

                // 设置列宽
                sheet.setColumnWidth(headers.length + day - 1, 15 * 256);

                // 设置表头和日期
                Cell headerCell = headerRow.createCell(headers.length + day - 1);
                headerCell.setCellValue(String.format("%d-%02d-%02d", year, monthNum, day));
                headerCell.setCellStyle(isWeekend ? weekendStyle : headerStyle);
            }

            // 添加示例数据
            Row exampleRow = sheet.createRow(1);
            exampleRow.createCell(0).setCellValue("1001"); // 工号
            exampleRow.createCell(1).setCellValue("张三"); // 姓名
            exampleRow.createCell(2).setCellValue("P2024001"); // 项目编号
            
            // 添加示例工时数据
            for (int i = 3; i < headerRow.getLastCellNum(); i++) {
                Cell cell = exampleRow.createCell(i);
                cell.setCellValue(8.0); // 示例工时数据
                cell.setCellStyle(headerStyle);
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("研发人员工时导入模板", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 写入响应
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (Exception e) {
            log.error("下载模板失败", e);
            throw new RuntimeException("下载模板失败：" + e.getMessage());
        }
    }

    /**
     * 导入研发人员工时数据
     */
    //@PreAuthorize("@ss.hasPermi('system:pworkhours:import')")
    @Log(title = "研发人员工时", businessType = BusinessType.IMPORT)
    @PostMapping("/importData")
    public AjaxResult importData(@RequestParam("file") MultipartFile file) throws Exception {
        try {
            // 验证文件
            if (file == null || file.isEmpty()) {
                return AjaxResult.error("请选择要导入的文件");
            }

            // 读取Excel文件
            Workbook workbook = WorkbookFactory.create(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null || sheet.getLastRowNum() < 1) {
                return AjaxResult.error("导入数据为空");
            }

            // 获取表头
            Row headerRow = sheet.getRow(0);
            if (headerRow == null || headerRow.getLastCellNum() < 4) {
                return AjaxResult.error("文件格式不正确，至少需要工号、姓名、项目编号和日期列");
            }

            // 验证工号列、姓名列和项目编号列
            if (!"工号".equals(getCellValueAsString(headerRow.getCell(0))) || 
                !"姓名".equals(getCellValueAsString(headerRow.getCell(1))) ||
                !"项目编号".equals(getCellValueAsString(headerRow.getCell(2)))) {
                return AjaxResult.error("文件格式不正确，第一列必须为工号，第二列必须为姓名，第三列必须为项目编号");
            }

            // 收集错误信息
            List<String> errorMessages = new ArrayList<>();
            // 用于检查工号是否重复
            Set<String> employeeNoSet = new HashSet<>();
            // 用于存储要导入的数据
            List<RdPworkhours> importList = new ArrayList<>();

            // 处理每一行数据
            for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null) continue;

                String employeeNo = getCellValueAsString(row.getCell(0));
                String employeeName = getCellValueAsString(row.getCell(1));
                String projectIdStr = getCellValueAsString(row.getCell(2));

                // 验证工号格式
                if (StringUtils.isEmpty(employeeNo)) {
                    errorMessages.add(String.format("第%d行：工号不能为空", rowIndex + 1));
                    continue;
                }

                // 检查工号是否重复
//                if (!employeeNoSet.add(employeeNo)) {
//                    errorMessages.add(String.format("第%d行：工号[%s]在导入文件中重复", rowIndex + 1, employeeNo));
//                    continue;
//                }

                // 验证工号是否存在
                SysUser user = sysUserMapper.selectUserByUserName(employeeNo);
                if (user == null) {
                    errorMessages.add(String.format("第%d行：工号[%s]不存在", rowIndex + 1, employeeNo));
                    continue;
                }

                // 验证项目编号
                if (StringUtils.isEmpty(projectIdStr)) {
                    errorMessages.add(String.format("第%d行：项目编号不能为空", rowIndex + 1));
                    continue;
                }

                // 处理每个日期的工时数据
                for (int i = 3; i < headerRow.getLastCellNum(); i++) {
                    String dateStr = getCellValueAsString(headerRow.getCell(i));
                    try {
                        // 解析日期
                        Date workDate = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
                        // 获取工时数据
                        String workHoursStr = getCellValueAsString(row.getCell(i));
                        if (!StringUtils.isEmpty(workHoursStr)) {
                            try {
                                double workHours = Double.parseDouble(workHoursStr);
                                // 检查是否已存在该日期的工时记录
                                RdPworkhours query = new RdPworkhours();
                                query.setUserName(employeeNo);
                                query.setProjectnumber(projectIdStr);
                                query.setWorkDate(workDate);
                                List<RdPworkhours> existList = rdPworkhoursService.selectRdPworkhoursList(query);
                                if (!existList.isEmpty()) {
                                    errorMessages.add(String.format("第%d行：工号[%s]在项目[%s]的[%s]已存在工时记录", 
                                        rowIndex + 1, employeeNo, projectIdStr, dateStr));
                                    continue;
                                }
                                // 创建工时记录
                                RdPworkhours workhours = new RdPworkhours();
                                workhours.setUserName(employeeNo);
                                workhours.setProjectnumber(projectIdStr);
                                workhours.setWorkDate(workDate);
                                workhours.setWorkhours(workHours); // 直接使用double类型
                                workhours.setStatus("0");
                                importList.add(workhours);
                            } catch (NumberFormatException e) {
                                errorMessages.add(String.format("第%d行：工号[%s]在项目[%s]的[%s]的工时数据格式不正确", 
                                    rowIndex + 1, employeeNo, projectIdStr, dateStr));
                            }
                        }
                    } catch (ParseException e) {
                        errorMessages.add(String.format("第%d行：工号[%s]的日期[%s]格式不正确", 
                            rowIndex + 1, employeeNo, dateStr));
                    }
                }
            }

            // 如果有错误信息，返回错误
            if (!errorMessages.isEmpty()) {
                //return AjaxResult.error(String.join("\n", errorMessages));
                Map<String,Object> map= new HashMap<String,Object>();
                map.put("successNum",0);
                map.put("failureNum",errorMessages.size());
                map.put("failureMsg",String.join("\n", errorMessages));

                //return map;
                return success(map);
            }

            // 批量保存数据
            int successCount = 0;
            if (!importList.isEmpty()) {
                for (RdPworkhours workhours : importList) {
                    successCount += rdPworkhoursService.insertRdPworkhours(workhours);
                }
            }

            Map<String,Object> map= new HashMap<String,Object>();
            map.put("successNum",successCount);
            map.put("failureNum",errorMessages.size());
            map.put("failureMsg",String.join("\n", errorMessages));

            //return map;
            return success(map);
        } catch (Exception e) {
            log.error("导入失败", e);
            return AjaxResult.error("导入失败：" + e.getMessage());
        }
    }

    /**
     * 获取单元格的值
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }
        String value = "";
        switch (cell.getCellType()) {
            case STRING:
                value = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    value = new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                } else {
                    value = String.valueOf(cell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                value = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                value = cell.getCellFormula();
                break;
            default:
                value = "";
        }
        return value;
    }
}
